#include "renderScene.h"
#include "myConstants.h"
#include "Axes.h"
#include "Floor.h"
#include "JetPlane.h"

#include "GLTools.h"
#include "GLShaderManager.h"
#include "GLMatrixStack.h"
#include "GLFrame.h"
#include "GLGeometryTransform.h"
#include "GLTriangleBatch.h"
#include "GLBatch.h"
#include "StopWatch.h"

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

extern GLShaderManager shaderManager;
extern GLMatrixStack modelViewMatrix; // Modelview Matrix
extern GLFrame cameraFrame;
extern GLFrame objectFrame;
extern GLFrame spheres[NUM_SPHERES];
extern GLGeometryTransform transformPipeline;
extern GLTriangleBatch sphereBatch;

M3DVector4f vLightEyePos;

// Called to draw scene
void renderScene(void) {
	static GLfloat vSphereColor[] = { 0.0f, 0.0f, 1.0f, 1.0f };

	GLBatch floorBatch;
	static Floor theFloor(&shaderManager, transformPipeline, floorBatch);
	// Time Based animation
	static CStopWatch rotTimer;
	//float yRot = rotTimer.GetElapsedSeconds() * 0.006f;

	// Clear the color and depth buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Draw the spinning Torus
	modelViewMatrix.Translate(0.0f, 0.0f, -2.5f);

	// Save the Translation
	modelViewMatrix.PushMatrix();

	modelViewMatrix.Translate(0.0f, -0.7f, 0.0f);

	// Apply a rotation and draw the torus
	modelViewMatrix.Scale(0.2f, 0.2f, 0.2f);
	//modelViewMatrix.Rotate(yRot, 0.0f, 1.0f, 0.0f);
	//modelViewMatrix.Translate(0.0f, 0.0f, -yRot);
	//modelViewMatrix.Scale(0.02f, 0.02f, 0.02f);
	// This is where the jetPlane is drawn

	M3DMatrix44f mObjectFrame;
	objectFrame.GetMatrix(mObjectFrame);
	modelViewMatrix.MultMatrix(mObjectFrame);

	GLTriangleBatch triangles;
	static JetPlane f16(&shaderManager, transformPipeline, triangles);

	f16.apearOnScreen();

	modelViewMatrix.PopMatrix(); // "Erase" the Rotation from before

	// Apply another rotation, followed by a translation, then draw the sphere
	/*modelViewMatrix.Rotate(yRot * -2.0f, 0.0f, 1.0f, 0.0f);
	 modelViewMatrix.Translate(1.0f, 0.0f, 0.0f);
	 shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, transformPipeline.GetModelViewMatrix(),
	 transformPipeline.GetProjectionMatrix(), vLightEyePos, vSphereColor);
	 sphereBatch.Draw();*/

	// Restore the previous modleview matrix (the identity matrix)
	modelViewMatrix.PopMatrix();
	modelViewMatrix.PopMatrix();

// Save the current modelview matrix (the identity matrix)
	modelViewMatrix.PushMatrix();

	//cameraFrame.MoveForward(yRot);

	M3DMatrix44f mCamera;
	cameraFrame.GetCameraMatrix(mCamera);
	modelViewMatrix.PushMatrix(mCamera);

	theFloor.apearOnScreen();

	GLBatch axesBatch;
	Axes theAxes(&shaderManager, transformPipeline, axesBatch);

	theAxes.apearOnScreen();

	for (int i = 0; i < NUM_SPHERES; i++) {
		modelViewMatrix.PushMatrix();
		modelViewMatrix.MultMatrix(spheres[i]);
		shaderManager.UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF,
				transformPipeline.GetModelViewMatrix(),
				transformPipeline.GetProjectionMatrix(), vLightEyePos,
				vSphereColor);
		sphereBatch.Draw();
		modelViewMatrix.PopMatrix();
	}

	// Transform the light position into eye coordinates
	M3DVector4f vLightPos = { 0.0f, 10.0f, 5.0f, 1.0f };
	m3dTransformVector4(vLightEyePos, vLightPos, mCamera);

	// Do the buffer Swap
	glutSwapBuffers();

	// Tell GLUT to do it again
	glutPostRedisplay();
}
